export default {
  install: function (Vue) {
    Vue.prototype.defaultHttpConfig = {
      options: { //发送给后台时携带cookie或者设置headers，或者传参数采用requestParameter
        withCredentials: true
      },
      fullSuccess: false, //是否成功的回调函数全部自己定义，如果为true则直接将response.data(后台返回数据在response.data中)放置到resolve中；如果为false，则提示消息全使用此函数默认提示方式，会将response.data[dataKey]放置到resolve中
      ignoreEmptyData: false, //是否忽略显示数据为空时的提示，默认是提示数据为空的，如果hideEmptyTip设置为true，则不提示
      emptyDataSuccess: false, //数据为空时，是否将后台返回数据放置在resolve中，默认数据为空，不定义回调函数
      emptyDataInfo: null, //数据为空时的提示信息，ignoreEmptyData和hideSuccessTip为false、null、undefined时，可提示自定义的数据为空的提示信息
      hideEmptyTip: false, //是否显示数据为空的消息提示，默认显示消息提示
      hideSuccessTip: false, //是否显示请求成功的提示，默认显示提示信息
      useDesc: true, //是否启用后台返回的desc字段作为提示信息
      hideErrorTip: false, //是否显示请求错误的提示，默认显示提示信息
      redirectUrl: '/views/login', //报403或者401错误时，重定向页面的路由
      messageKey: 'message', //后台放置提示消息的字段
      dataKey: 'data', //后台放置前台需求数据的字段
    };
    Vue.prototype.httpClient = function (self, config) {
      let me = this;
      let request = null,
        options = {},
        hasOptions = false;
      if (!self._.isEmpty(config.options)) {
        //传入了options
        options = config.options;
        hasOptions = true;
      } else {
        options = self.defaultHttpConfig.options;
        hasOptions = !self._.isEmpty(options);
      }
      if (self._.isEmpty(config.url)) {
        me.message(self, "warn", "必须传入请求后台的url");
        return;
      }
      if (self._.isEmpty(config.type)) {

        request = hasOptions ?
          self.axios.get(config.url, options) :
          self.axios.get(config.url);
      } else {
        switch (config.type.toLowerCase()) {
          case "get":
            request = hasOptions ?
              self.axios.get(config.url, options) :
              self.axios.get(config.url);
            break;
          case "post":
            let postParam = null;
            if (me.isEmpty(config.param)) {
              postParam = self.defaultHttpConfig.param;
            } else {
              postParam = config.param;
            }
            request = hasOptions ?
              self.axios.post(config.url, postParam, options) :
              self.axios.post(config.url, postParam);
            break;
          case "put":
            let putParam = null;
            if (self._.isEmpty(config.param)) {
              putParam = self.defaultHttpConfig.param;
            } else {
              putParam = config.param;
            }
            request = hasOptions ?
              self.axios.put(config.url, putParam, options) :
              self.axios.put(config.url, putParam);
            break;
          case "delete":
            request = hasOptions ?
              self.axios.delete(config.url, options) :
              self.axios.delete(config.url);
            break;
          default:
            request = null;
            break;
        }
      }
      if (request == null) return;
      request.then((response) => {
        let res = response.data;
        if (!config.fullSuccess) {
          let data = res[me.defaultHttpConfig.dataKey];
          if (!config.ignoreEmptyData) {
            if (me.isEmpty(data)) {
              !config.hideEmptyTip && (config.showEmptyInfo ? me.message(self,
                "success",
                res[me.defaultHttpConfig.messageKey]
              ) : me.message(self,
                "info",
                config.emptyDataInfo ? config.emptyDataInfo : "数据为空"
              ))

              config.emptyDataSuccess && config.emptySuccess(data);
            } else {
              !config.hideSuccessTip &&
                me.message(self, "success", res[me.defaultHttpConfig.messageKey]);
              config.success(data);
            }
          } else {
            !config.hideSuccessTip &&
              me.message(self, "success", res[me.defaultHttpConfig.messageKey]);
            config.success(data);
          }
        } else {
          config.success(res);
        }
      }).catch(function (error) {
        console.log('error', error);
        if (config.hideErrorTip) return;
        let err = error.response;
        let res = err.data;
        if (config.hasError) {
          config.error(err);
        } else {
          if (self._.isEmpty(res)) {
            me.message(self, 'error', err.statusText);
            return;
          }
          if (err.status == 403 || err.status == 401) {
            let info = null;
            if (config.useDesc) {
              info = me.isEmpty(res["desc"]) ?
                res[me.defaultHttpConfig.messageKey] :
                res["desc"];
            } else {
              info = res[me.defaultHttpConfig.messageKey];
            }
            let str = info + '<br>3s后跳转至登录页';
            this.message(self, 'warn', str, true);
            setTimeout(() => {
              self.$router.push({
                path: '/pages/login'
              })
            }, 3000)
          } else {
            let info = null;
            if (config.useDesc) {
              info = me.isEmpty(res["desc"]) ?
                res[me.defaultHttpConfig.messageKey] :
                res["desc"];
            } else {
              info = res[me.defaultHttpConfig.messageKey];
            }
            me.message(self, 'error', info);
          }
        }
      })
      return request;
    };
    Vue.prototype.timeDateFormat = function (t, fmt, way) {
      let time = new Date(t);
      let timeWay = way || "bj";
      let y = "yyyy",
        M = "MM",
        d = "dd",
        h = "hh",
        m = "mm",
        s = "ss";
      let splitArr = [fmt.slice(y.length, fmt.indexOf(M)), fmt.slice(M.length + fmt.indexOf(M), fmt.indexOf(d)), fmt.slice(d.length + fmt.indexOf(d), fmt.indexOf(h)), fmt.slice("hh".length + fmt.indexOf(h), fmt.indexOf(m)), fmt.slice(m.length + fmt.indexOf(m), fmt.indexOf(s))];
      let year, month, date, hour, minute, seconds;
      if (timeWay == "utc") {
        year = time.getUTCFullYear();
        month = time.getUTCMonth() + 1;
        date = time.getUTCDate();
        hour = time.getUTCHours();
        minute = time.getUTCMinutes();
        seconds = time.getUTCSeconds();
      } else {
        year = time.getFullYear();
        month = time.getMonth() + 1;
        date = time.getDate();
        hour = time.getHours();
        minute = time.getMinutes();
        seconds = time.getSeconds();
      }
      splitArr[2].indexOf("zh-dayName") != -1 && (splitArr[2] = (hour > 12 ? " 下午" : " 上午"));
      splitArr[2].indexOf("en-dayName") != -1 && (splitArr[2] = (hour > 12 ? " PM" : " AM"));
      let fmtDate = year + splitArr[0] + (String(month).length == 1 ? ("0" + month) : month) + splitArr[1] + (String(date).length == 1 ? ("0" + date) : date) + splitArr[2] + (String(hour).length == 1 ? ("0" + hour) : hour) + splitArr[3] + (String(minute).length == 1 ? ("0" + minute) : minute) + splitArr[4] + (String(seconds).length == 1 ? ("0" + seconds) : seconds);
      return fmtDate;
    };
    Vue.prototype.isEmptyObject = function (obj) {
      for (let key in obj) {
        if (key) {
          return false;
        }
      }
      return true;
    };
    //比较2个简单的对象是否相等，不能比较json
    Vue.prototype.isEqualObject = function (obj1, obj2) {
      let keys1 = Object.keys(obj1);
      let keys2 = Object.keys(obj2);
      let isSame = this.isRepeatArray(keys1, keys2);
      if (!isSame) return false;
      let isEqual = true;
      for (let key in obj1) {
        obj1[key] != obj2[key] && (isEqual = false);
      }
      return isEqual;
    };
    Vue.prototype.isRepeatArray = function (arr1, arr2) {
      if (!arr1 || !arr2) return false;
      if (arr1.length != arr2.length) return false;
      let isSame = true;
      arr1.forEach((d) => {
        arr2.indexOf(d) == -1 && (isSame = false);
      })
      return isSame;
    };
    Vue.prototype.isEqualArray = function (array, array1) {
      if (!array)
        return false;
      if (array1.length != array.length)
        return false;
      for (let i = 0, l = array1.length; i < l; i++) {
        if (array1[i] instanceof Array && array[i] instanceof Array) {
          if (!array1[i] == (array[i]))
            return false;
        } else if (array1[i] != array[i]) {
          return false;
        }
      }
      return true;
    };
    Vue.prototype.isObjOrArr = function (obj) {
      let str = '';
      if (obj instanceof Array) {
        str = 'array';
      } else if (obj instanceof Object) {
        str = 'object';
      } else {
        let tmp = typeof (obj);
        tmp.toLowerCase();
        str = tmp;
      }
      return str;
    };
    Vue.prototype.cloneObj = function (obj) {
      if (obj == null || obj == undefined) {
        return;
      }
      let newobj = obj.constructor === Array ? [] : {};
      if (typeof obj !== 'object') {
        return obj;
      }
      else {
        for (let i in obj) {
          newobj[i] = (typeof obj[i] === 'object' ? this.cloneObj(obj[i]) : obj[i]);
        }
      }
      return newobj;
    };
    Vue.prototype.firstLetterToUpperCase = function (str) {
      return str.substring(0, 1).toUpperCase() + str.substring(1);
    };
    Vue.prototype.checkRequire = function (arr) {
      let str = '';
      arr.forEach((d) => {
        if (d.required) {
          if (d.label != '备注') {
            if (d.value == null || d.value == undefined || (d.value == '' && (typeof d.value == 'string')) || ((typeof d.value == 'object') && d.value.length === 0)) {
              if (d.label) {
                str += d.label + '字段不能为空<br/>'
              } else {
                str += d.value + '字段不能为空<br/>'
              }
            }
          }
        }
      })
      return str;
    };
    Vue.prototype.checkReg = function (str, type) {
      let reg = null;
      if (type.indexOf('身份证') != -1 || type.indexOf('证件') != -1) {
        //15位  18位
        reg = /(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}[0-9Xx]$)/;
      } else if (type.indexOf('手机') != -1) {
        reg = /(^((\(\d{3}\))|(\d{3}\-))?(1[3578]\d{9})$)/;
      } else if (type.indexOf('电话') != -1) {
        reg = /(^(0[0-9]{2,3}\-)?([2-9][0-9]{6,7})+(\-[0-9]{1,4})?$)|(^(400)-(\d{3})-(\d{4})(.)(\d{1,4})$)|(^(400)-(\d{3})-(\d{4}$))/;
      } else if (type.indexOf('银行账户') != -1 || type.indexOf('银行卡号') != -1) {
        reg = /^(\d{16}|\d{18}$)/;
      } else if (type.indexOf('信用代码') != -1) {
        reg = /^([0-9A-Za-z]{18})$/;
      } else if (type.indexOf('邮箱') != -1) {
        reg = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/;
      } else if (type == '邮政编码' || type == '邮编') {
        reg = /^[0-9]{6}$/;
      } else {
        switch (type) {
          case '用户名包含汉字':
            // reg = /^(?![_|\d])[a-zA-Z0-9\u4e00-\u9fa5]+$/; //只能是字母，数字，_，汉字 ；  不能以数字、下划线开头
            reg = /^[a-zA-Z0-9\u4e00-\u9fa5]+$/; //只能是字母，数字，汉字 ；
            break;
          case '注册账号':
            // reg = /^(?![_|\d])[a-zA-Z0-9\u4e00-\u9fa5]+$/; //只能是字母，数字，_，汉字 ；  不能以数字、下划线开头
            break;
          case '用户名':
            reg = /^(?![_|\d])\w{4,}$/; //只能是字母，数字，_ ；  不能以数字、下划线开头
            break;
          case '密码':
            reg = /^(\w){0,20}$/;
            // reg = /^[a-zA-Z0-9`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~！@#￥%……&*（）——\-+={}|《》？：“”【】、；‘’，。、]{8,20}$/;  //只能是字母，数字，_ ；   不能以数字、下划线开头,长度8-20
            break;
          default:
            break;
        }
      }
      if (reg == null) {
        return true;
      } else {
        /*let flag = false;
        if(type.indexOf('身份证') != -1 || type.indexOf('证件') != -1){
          console.log('身份证',str);
          console.log('身份证',reg.test(str));
        }else{
          flag = reg.test(str);
        }*/

        return reg.test(str);
      }
    };
    Vue.prototype.mergeObj = function (arr) {
      let newObj = {};
      arr.forEach((d, i) => {
        if (i != 0) {
          let currKeys = Object.keys(d);
          currKeys.forEach((k) => {
            newObj[k] = d[k];
          })
        } else {
          newObj = this.cloneObj(d);
        }
      })
      return newObj;
    };
    Vue.prototype.isEmpty = function (a) {
      if (a == null || a == undefined || a === '') {
        return true;
      } else {
        return false;
      }
    };
    Vue.prototype.createuuid = function () {
      var s = [];
      var hexDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      for (var i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
      }
      s[14] = "4"
      s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1)
      s[8] = s[13] = s[18] = s[23] = "-"
      let uuid = s.join("")
      return uuid
    };
    Vue.prototype.getSearchResult = function (param, data) {
      let arr = [];
      for (let key in param) {
        if (arr.length == 0) {
          arr.push(this.getResultArr(data, key, param));
        } else {
          arr.push(this.getResultArr(arr[arr.length - 1], key, param));
        }
      }
      return arr[arr.length - 1];
    };
    Vue.prototype.getResultArr = function (arr, key, param) {
      let tmp = [];
      arr.forEach((d) => {
        Object.keys(d).forEach((k) => {
          k == key && param[key] == d[k] && (tmp.push(d));
        })
      })
      return tmp;
    };
    Vue.prototype.getDayCountOfCurrentMonth = function (year, month) {
      let isLeapYear = false;
      if (year % 4 == 0 && year % 400 != 0) {
        isLeapYear = true;
      }
      let days = 0;
      let _31Day = [1, 3, 5, 7, 8, 10, 12];
      if (month == 2) {
        days = (isLeapYear ? 29 : 28);
      } else {
        if (_31Day.indexOf(month) != -1) {
          days = 31;
        } else {
          days = 30;
        }
      }
      return days;
    };
    Vue.prototype.getPreTime = function (now, days) {
      let currentTime = now.getTime();
      let timeInterval = days * 24 * 3600 * 1000;
      let preTime = currentTime - timeInterval;
      let time = this.dateFormat(preTime, 'yyyy-MM-dd hh:mm:ss');
      return time;
    };
    Vue.prototype.setDefaultTableParam = function (number, size, sortField, sortOrder, filter) {
      let param = {
        pageNumber: number ? number : 1,
        pageSize: size ? size : 10
      };
      sortField && (param['sortField'] = sortField);
      sortOrder && (param['sortOrder'] = sortOrder);
      filter && (param['filter'] = filter);
      return param;
    };
    Vue.prototype.sortByTime = function (arr, sortField, sortOrder) { //arr:需要排序的数组 sortField:排序字段 sortOrder:排序方式 true为升序 false为降序
      let newArr = [];
      arr.forEach((d, i) => {
        if (i == 0) {
          newArr.push(d);
        } else {
          if (sortOrder == 'ascending') {
            if (newArr.length == 1) {
              let pre = new Date(newArr[0][sortField]).getTime(),
                curr = new Date(d[sortField]).getTime();
              if (pre < curr) {
                newArr.push(d);
              } else {
                newArr.unshift(d);
              }
            } else {
              newArr.every((a, index) => {
                let pre = new Date(a[sortField]).getTime(),
                  curr = new Date(d[sortField]).getTime();
                if (index == 0) {
                  if (curr < pre) {
                    newArr.unshift(d);
                    return false;
                  } else {
                    return true;
                  }
                } else if (index == newArr.length - 1) {
                  if (curr > pre) {
                    newArr.push(d);
                  } else {
                    newArr.splice(index, 0, d);
                  }
                  return false;
                } else {
                  if (curr > pre) {
                    return true;
                  } else {
                    newArr.splice(index, 0, d);
                    return false;
                  }
                }
              })
            }
          } else {
            if (newArr.length == 1) {
              let pre = new Date(newArr[0][sortField]).getTime(),
                curr = new Date(d[sortField]).getTime();
              if (pre < curr) {
                newArr.unshift(d);
              } else {
                newArr.push(d);
              }
            } else {
              newArr.every((a, index) => {
                let pre = new Date(a[sortField]).getTime(),
                  curr = new Date(d[sortField]).getTime();
                if (index == 0) {
                  if (curr > pre) {
                    newArr.unshift(d);
                    return false;
                  } else {
                    return true;
                  }
                } else if (index == newArr.length - 1) {
                  if (curr < pre) {
                    newArr.push(d);
                  } else {
                    newArr.splice(index, 0, d);
                  }
                  return false;
                } else {
                  if (curr < pre) {
                    return true;
                  } else {
                    newArr.splice(index, 0, d);
                    return false;
                  }
                }
              })
            }
          }
        }
      })
      return newArr;
    };
    Vue.prototype.message = function (me, str, info, useHTML, showClose, time) {
      let tmpTime = time ? time : 3000;
      let show = (showClose == null || showClose == undefined ? true : showClose);
      switch (str) {
        case 'success':
          me.$notify({
            title: '成功',
            message: info,
            offset: 100,
            showClose: show,
            duration: tmpTime,
            dangerouslyUseHTMLString: useHTML,
            type: 'success'
          });

          break;
        case 'info':
          me.$notify.info({
            title: '提示',
            showClose: show,
            dangerouslyUseHTMLString: useHTML,
            offset: 100,
            duration: tmpTime,
            message: info
          });
          break;
        case 'warn':
          me.$notify({
            title: '警告',
            offset: 100,
            message: info,
            showClose: show,
            duration: tmpTime,
            dangerouslyUseHTMLString: useHTML,
            type: 'warning'
          });
          break;
        case 'error':
          me.$notify.error({
            title: '错误',
            showClose: show,
            dangerouslyUseHTMLString: useHTML,
            offset: 100,
            duration: tmpTime,
            message: info
          });
          break;
        default:
          me.$notify.info({
            title: '提示',
            showClose: show,
            dangerouslyUseHTMLString: useHTML,
            offset: 100,
            duration: tmpTime,
            message: info
          });
          break;
      }
    };
    Vue.prototype.messageAlert = function (me, str, info, useHTML, showClose) {
      let show = (showClose == null || showClose == undefiend ? true : showClose);
      switch (str) {
        case 'success':
          me.$message({
            dangerouslyUseHTMLString: useHTML,
            message: info,
            showClose: show,
            type: 'success'
          });
          break;
        case 'info':
          me.$message({
            dangerouslyUseHTMLString: useHTML,
            message: info,
            showClose: show,
            type: 'info'
          });
          break;
        case 'warn':
          me.$message({
            dangerouslyUseHTMLString: useHTML,
            message: info,
            showClose: show,
            type: 'warning'
          });
          break;
        case 'error':
          me.$message.error(info);
          break;
        default:
          me.$message({
            dangerouslyUseHTMLString: useHTML,
            message: str,
            showClose: show,
            type: 'info'
          });
          break;
      }
    };
    //判断浏览器类型和版本
    Vue.prototype.getBrowserInfo = function () {
      /*var Sys = {};
      var ua = navigator.userAgent.toLowerCase();
      var re =/(msie|firefox|chrome|opera|version).*?([\d.]+)/;
      var m = ua.match(re);
      Sys.browser = m[1].replace(/version/, "'safari");
      Sys.ver = m[2];
      return Sys;*/
      var agent = navigator.userAgent.toLowerCase();
      var regStr_ie = /msie [\d.]+;/gi;
      var regStr_ff = /firefox\/[\d.]+/gi
      var regStr_chrome = /chrome\/[\d.]+/gi;
      var regStr_saf = /safari\/[\d.]+/gi;
      var isIE = agent.indexOf("compatible") > -1 && agent.indexOf("msie" > -1); //判断是否IE<11浏览器
      var isEdge = agent.indexOf("edge") > -1 && !isIE; //判断是否IE的Edge浏览器
      var isIE11 = agent.indexOf('trident') > -1 && agent.indexOf("rv:11.0") > -1;
      if (isIE) {
        var reIE = new RegExp("msie (\\d+\\.\\d+);");
        reIE.test(agent);
        var fIEVersion = parseFloat(RegExp["$1"]);
        if (fIEVersion == 7) {
          return "IE/7";
        } else if (fIEVersion == 8) {
          return "IE/8";
        } else if (fIEVersion == 9) {
          return "IE/9";
        } else if (fIEVersion == 10) {
          return "IE/10";
        }
      } //isIE end
      if (isIE11) {
        return "IE/11";
      }
      //firefox
      if (agent.indexOf("firefox") > 0) {
        return agent.match(regStr_ff);
      }
      //Safari
      if (agent.indexOf("safari") > 0 && agent.indexOf("chrome") < 0) {
        return agent.match(regStr_saf);
      }
      //Chrome
      if (agent.indexOf("chrome") > 0) {
        return agent.match(regStr_chrome);
      }
    };
    Vue.prototype.formatterResponse = function (res) {
      let newRes = this.cloneObj(res);
      delete newRes.desc;
      delete newRes.message;
      delete newRes.tookInMillis;
      delete newRes.requestURL;
      return newRes;
    };
    Vue.prototype.timeFormatInit = function (t) {
      let date = new Date(t);
      let year = date.getFullYear();
      let month = date.getMonth() + 1;
      let day = date.getDate();
      let hours = date.getHours();
      let minutes = date.getMinutes();
      let seconds = date.getSeconds();
      month < 10 && (month = '0' + month);
      day < 10 && (day = '0' + day);
      hours < 10 && (hours = '0' + hours);
      minutes < 10 && (minutes = '0' + minutes);
      seconds < 10 && (seconds = '0' + seconds);
      let format = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
      return format;
    }
  }

}
